<template>
    <!-- 从setup中取值 -->
    <div><strong>从setup中取值：</strong>{{ hello }} {{ version }}</div>
    <!-- 从vue2 data配置项中取值 -->
    <div><strong>从vue2 data配置项中取值：</strong>{{ str }}</div>
    <!-- 测试vue2、3中的重复变量值 -->
    <div><strong>测试vue2、3中的重复变量值：</strong>{{ num }}</div>
    <br />
    <button @click="onClick">study setup</button>

    <!-- 如果vue2的代码在前，vue3的代码在后，则vue3中 无法 读取到vue2中的数据。反之可以读取到 -->
    <br />
    <button @click="test1">vue3中 读取 vue2的数据<span style="color: red"> x </span></button>

    <br />
    <button @click="test2">vue2中 读取 vue3的数据<span style="color: green"> √ </span></button>

    <!-- 响应式 2023年12月11日 -->
    <div>
        <hr/>
        <p><strong>学习响应式</strong></p>

        ref：<br/>
        计数器：{{ count }}  
        <button @click="countAdd">+</button>  
        <br/>
        姓名：{{ person.name }}
        <button @click="changeName">换个名字</button>  
        <br/>
        年龄：{{ person.age }}
        <br/><br/>

        reactive：<br/>
        姓名：{{ student.name }}
        <button @click="changeStudentName">换个名字</button>  
        <br/>
        学号：{{ student.id }}
        <br/>
        性别：{{ student.sex }}
        <br/>
        <div v-show="student.hobby">
            爱好：{{ student.hobby }}
            <button @click="deleteHobby">删除爱好</button> 
        </div>
        <button @click="addHobby">添加爱好</button>  
        
        <br/><br/>
        <button @click="emitHello">触发hello事件</button>  

        <!-- 学习computed -->
        <br/><br/>
        computed : <br/>
        姓 : <input type="text" v-model="pet.firstName">
        <br/>
        名 : <input type="text" v-model="pet.lastName">
        <br/>
        全名 : <input type="text" v-model="pet.fullName">
        <br/>
        全名 : {{ pet.fullName }}

        <!-- 学习watch -->
        <br/><br/>
        watch : <br/>
        student.pet.name : {{ student.pet.name }}
        <button @click="student.pet.name += '~'">修改student.pet.name</button>  
    </div>
</template>

<script>
//引入渲染函数
import { h } from 'vue'
import { ref, reactive, computed, watch, watchEffect } from 'vue'
export default {
    name: 'Study_setup',
    props: {
        msg: {
            type: String
        }
    },
    emits:{
        //声明事件
        hello: {
            
        }
    },
    //vue3
    setup(props, contxt) {
        console.log('------setup------')
        console.log(' --this-->', this)
        console.log(' --参数1-->', props)
        console.log(' --参数2-->', contxt)

        let hello = `hello vue`
        let version = 3
        let num = 200//重复

        function test1() {
            console.log(this.str)
        }

        //响应式数据
        let count = ref(0)
        console.log('ref响应式数据--count-->', count)

        function countAdd() {
            count.value++
        }

        let person = ref({
            name: 'badpig',
            age: 24
        })
        console.log('ref响应式数据--person-->', person)

        function changeName() {
            person.value.name = '坏猪'
        }

        //reactive
        const student = reactive({
            name: '学霸',
            id: 'stu001',
            sex: '男',
            pet: {
                name: '小咪',
                type: 'cat'
            }
        })
        console.log('reactive响应式数据--student-->', student)

        function changeStudentName() {
            student.name = '学渣'
        }

        //vue3中可直接添加、删除属性 （响应式的）
        function addHobby() {
            student.hobby = []
            student.hobby[0] = '学习！'
            student.hobby[1] = '睡觉！'
        }

        function deleteHobby() {
            delete student.hobby
        }

        function emitHello() {
            contxt.emit('hello')
        }

        //学习computed
        const pet = reactive({
            firstName: '小',
            lastName: '咪'
        })
        //简写
        // pet.fullName = computed(() => {
        //     return pet.firstName + '-' + pet.lastName
        // })
        //完整
        pet.fullName = computed({
            get() {
                return pet.firstName + '-' + pet.lastName
            },
            set(value) {
                if (value.includes('-')) {
                    let split = value.split('-')
                    pet.firstName = split[0]
                    pet.lastName = split[1]
                }
            }
        })

        //学习watch
        //监听单个数据
        watch(
            count, 
            (newVal, oldVal) => {
                console.log(`单监听 —— count变了 ${oldVal} ——> ${newVal}`)
            }, 
            {
                immediate: true
            }
        )
        //监听多个数据
        let helloRef = ref(hello)
        let versionRef = ref(version)
        watch(
            [helloRef, versionRef],
            (newVal, oldVal) => {
                console.log('多监听', newVal, oldVal)
            },
            {
                immediate: true
            }
        )
        //监听对象（reactive）
        watch(
            student, 
            (newVal, oldVal) => {
                console.log('student变了', newVal.name, oldVal.name)
            }
        )
        //监听对象中的单个属性   
        watch(
            () => student.name, 
            (newVal, oldVal) => {
                console.log('student.name变了', newVal, oldVal)
            }
        )
        //监听A对象中的B对象(student是A，pet是B，如B对象中的属性变化了想监视到需要配置deep参数，但由于B也是对象所以这里newVal和oldVal也存在问题)
        watch(
            () => student.pet,
            (newVal, oldVal) => {
                console.log('监听对象中的对象', newVal, oldVal)
            },
            {deep: true}
        )
        //tips
        //监听ref定义的对象
        //方式一
        watch(
            person.value, 
            (newVal, oldVal) => {
                console.log('person变了(方式一)', newVal.name, oldVal.name)
            }
        )
        //方式二
        watch(
            person, 
            (newVal, oldVal) => {
                console.log('person变了(方式二)', newVal.name, oldVal.name)
            },
            {deep: true}
        )

        //学习watchEffect, 回调函数里用到了什么，其如果变了的话，回调函数会被调用一次；初始化时调用一次。
        watchEffect(() => {
            let temp = count.value
            let temp2 = student.name
            console.log('---watchEffect---')
        })

        //1、返回对象
        return {
            hello,
            version,
            onClick() {
                alert(hello + version + '!!!')
            },
            num,
            test1,
            count,
            countAdd,
            person,
            changeName,
            student,
            changeStudentName,
            addHobby,
            deleteHobby,
            emitHello,
            pet
        }

        //2、返回渲染函数
        // return () => h('p', '芜湖')
    },

    beforeCreate() {
        console.log('------beforeCreate------')
    },

    //vue2
    data() {
        return {
            str: '这是vue2中的值',
            num: 100,//重复,
        }
    },
    methods: {
        test2() {
            console.log(this.hello)
        }
    },
    watch: {
        'student.name'(newVal, oldVal) {
            console.log(`student.name变了（vu2写法） ${oldVal} -> ${newVal}`)
        }
    }
}
</script>

<style>
div {
    text-align: left
}
</style>